package com.gzc.just.play.last.war.robotclient;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;

import com.gzc.just.play.last.war.common.scanner.MessageHandlerScanner;

/**
 * 机器人客户端管理器
 * 基于C++ RobotMgr类实现
 */
@Component
public class RobotClientManager {
    private static final Logger logger = LoggerFactory.getLogger(RobotClientManager.class);
    
    @Autowired
    private RobotClientProperties properties;

    @Autowired
    private MessageHandlerScanner messageHandlerScanner;
    
    @Autowired(required = false)
    private NacosServiceWatcher nacosServiceWatcher;
    
    // 状态
    private final AtomicBoolean running = new AtomicBoolean(false);
    private volatile long startTime = 0;
    
    // 机器人客户端列表
    private final Map<Long, RobotClient> robotClients = new ConcurrentHashMap<>();
    
    // 线程池
    private final ExecutorService executorService = Executors.newCachedThreadPool();
    private final ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(2);
    
    /**
     * 初始化
     */
    public void initialize() {
        if (!properties.isEnabled()) {
            logger.info("Robot client is disabled, skipping initialization");
            return;
        }
        
        logger.info("Initializing robot client manager...");
        
        running.set(true);
        startTime = System.currentTimeMillis();
        
        // 初始化Nacos服务发现
        if (nacosServiceWatcher != null) {
            try {
                nacosServiceWatcher.start();
                logger.info("Nacos service watcher started");
                
                // 更新服务器地址配置
                updateServerAddresses();
            } catch (Exception e) {
                logger.warn("Failed to start Nacos service watcher, using default server addresses", e);
            }
        } else {
            logger.info("Nacos service watcher not available, using default server addresses");
        }
        
        // 启动心跳检查任务
        scheduledExecutor.scheduleAtFixedRate(this::checkHeartbeats, 30, 30, TimeUnit.SECONDS);
        
        // 启动统计报告任务
        scheduledExecutor.scheduleAtFixedRate(this::reportStatistics, 60, 60, TimeUnit.SECONDS);
        
        // 启动服务器地址更新任务
        scheduledExecutor.scheduleAtFixedRate(this::updateServerAddresses, 0, 30, TimeUnit.SECONDS);
        
        logger.info("Robot client manager initialized successfully");
    }
    
    /**
     * 创建机器人客户端
     */
    public RobotClient createRobot(RobotClientConfig config) {
        RobotClient robot = new RobotClient(
                config.getRobotId(),
                config.getUsername(),
                config.getPassword(),
                config.getNickname(),
                messageHandlerScanner
        );
        
        // 连接到登录服务器
        if (robot.connect(config.getLoginServerHost(), config.getLoginServerPort())) {
            robotClients.put(config.getRobotId(), robot);
            logger.info("Robot {} created and connected", config.getRobotId());
        } else {
            logger.error("Failed to create robot {}", config.getRobotId());
        }
        
        return robot;
    }
    
    /**
     * 创建多个机器人
     */
    public void createRobots(int count, RobotClientConfig templateConfig) {
        logger.info("Creating {} robots with template: {}", count, templateConfig);
        
        for (int i = 0; i < count; i++) {
            long robotId = templateConfig.getRobotId() + i;
            
            RobotClientConfig config = new RobotClientConfig(
                    robotId,
                    templateConfig.getUsername() + "_" + robotId,
                    templateConfig.getPassword(),
                    templateConfig.getNickname() + "_" + robotId
            );
            
            // 复制其他配置
            config.setSex(templateConfig.getSex());
            config.setHeaderId(templateConfig.getHeaderId());
            config.setPlatformId(templateConfig.getPlatformId());
            config.setLoginServerHost(templateConfig.getLoginServerHost());
            config.setLoginServerPort(templateConfig.getLoginServerPort());
            config.setGateServerHost(templateConfig.getGateServerHost());
            config.setGateServerPort(templateConfig.getGateServerPort());
            config.setEnableAI(templateConfig.isEnableAI());
            config.setAiType(templateConfig.getAiType());
            
            createRobot(config);
        }
        
        logger.info("{} robots created successfully", count);
    }
    
    /**
     * 断开机器人
     */
    public void disconnectRobot(long robotId) {
        RobotClient robot = robotClients.get(robotId);
        if (robot != null) {
            robot.disconnect();
            robotClients.remove(robotId);
            logger.info("Robot {} disconnected and removed", robotId);
        }
    }
    
    /**
     * 断开所有机器人
     */
    public void disconnectAllRobots() {
        logger.info("Disconnecting all robots...");
        
        robotClients.forEach((id, robot) -> {
            robot.disconnect();
            logger.debug("Robot {} disconnected", id);
        });
        
        robotClients.clear();
        logger.info("All robots disconnected");
    }
    
    /**
     * 获取机器人客户端
     */
    public RobotClient getRobot(long robotId) {
        return robotClients.get(robotId);
    }
    
    /**
     * 获取所有机器人客户端
     */
    public List<RobotClient> getAllRobots() {
        return new ArrayList<>(robotClients.values());
    }
    
    /**
     * 获取机器人数量
     */
    public int getRobotCount() {
        return robotClients.size();
    }
    
    /**
     * 检查心跳
     */
    private void checkHeartbeats() {
        if (!running.get()) {
            return;
        }
        
        long currentTime = System.currentTimeMillis();
        long timeoutMs = 60000; // 60秒超时
        
        robotClients.forEach((id, robot) -> {
            if (robot.isConnected() && 
                (currentTime - robot.getLastHeartbeatTime() > timeoutMs)) {
                
                logger.warn("Robot {} heartbeat timeout, reconnecting...", id);
                
                // 重连逻辑
                executorService.submit(() -> {
                    try {
                        // 简化的重连逻辑
                        Thread.sleep(1000);
                        logger.info("Robot {} reconnected", id);
                    } catch (Exception e) {
                        logger.error("Robot {} failed to reconnect: {}", id, e.getMessage(), e);
                    }
                });
            }
        });
    }
    
    /**
     * 报告统计信息
     */
    private void reportStatistics() {
        if (!running.get()) {
            return;
        }
        
        long totalMessages = robotClients.values().stream()
                .mapToLong(RobotClient::getMessageCount)
                .sum();
        
        long totalSent = robotClients.values().stream()
                .mapToLong(RobotClient::getSendCount)
                .sum();
        
        long totalRecv = robotClients.values().stream()
                .mapToLong(RobotClient::getRecvCount)
                .sum();
        
        long connectedCount = robotClients.values().stream()
                .mapToLong(robot -> robot.isConnected() ? 1 : 0)
                .sum();
        
        logger.info("Robot statistics: total={}, connected={}, messages={}, sent={}, recv={}", 
                robotClients.size(), connectedCount, totalMessages, totalSent, totalRecv);
    }
    
    /**
     * 更新服务器地址
     */
    private void updateServerAddresses() {
        if (nacosServiceWatcher != null) {
            try {
                // 获取最新的登录服务器地址
                String loginHost = nacosServiceWatcher.getLoginServerHost();
                int loginPort = nacosServiceWatcher.getLoginServerPort();
                
                // 获取最新的网关服务器地址
                String gateHost = nacosServiceWatcher.getGateServerHost();
                int gatePort = nacosServiceWatcher.getGateServerPort();
                
                // 更新配置
                properties.getLoginServer().setHost(loginHost);
                properties.getLoginServer().setPort(loginPort);
                properties.getGateServer().setHost(gateHost);
                properties.getGateServer().setPort(gatePort);
                
                if (logger.isDebugEnabled()) {
                    logger.debug("Updated server addresses from Nacos: login={}:{}, gate={}:{}", 
                            loginHost, loginPort, gateHost, gatePort);
                }
            } catch (Exception e) {
                logger.warn("Failed to update server addresses from Nacos", e);
            }
        }
    }
    
    /**
     * 清理资源
     */
    public void cleanup() {
        running.set(false);
        
        disconnectAllRobots();
        
        // 停止Nacos服务监听
        if (nacosServiceWatcher != null) {
            try {
                nacosServiceWatcher.stop();
                logger.info("Nacos service watcher stopped");
            } catch (Exception e) {
                logger.error("Failed to stop Nacos service watcher", e);
            }
        }
        
        executorService.shutdown();
        scheduledExecutor.shutdown();
        
        try {
            if (!executorService.awaitTermination(10, TimeUnit.SECONDS)) {
                executorService.shutdownNow();
            }
            
            if (!scheduledExecutor.awaitTermination(10, TimeUnit.SECONDS)) {
                scheduledExecutor.shutdownNow();
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            logger.error("Interrupted while waiting for shutdown", e);
        }
        
        logger.info("Robot client manager shutdown completed");
    }
    
    // Getters
    public boolean isRunning() {
        return running.get();
    }
    
    public long getStartTime() {
        return startTime;
    }
    
    public long getUptime() {
        return running.get() ? System.currentTimeMillis() - startTime : 0;
    }
}